package cn.iocoder.yudao.module.erp.service.dp;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.common.LocalDateAdapter;
import cn.iocoder.yudao.module.erp.controller.admin.common.LocalDateTimeAdapter;
import cn.iocoder.yudao.module.erp.controller.admin.dispatchvehicle.vo.DispatchVehicleSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpgz.vo.DpGzPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpgz.vo.DpGzSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.dp.vo.DpSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dispatchvehicle.DispatchVehicleDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dp.DpGzDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemGzDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dplist.DpEastListGzDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dplist.DpWestListGzDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.supplierfleet.SupplierFleetDO;
import cn.iocoder.yudao.module.erp.dal.mysql.dispatchvehicle.DispatchVehicleMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dp.DpGzMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dpitem.DpItemGzMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dpeast.DpEastListGzMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.dpwest.DpWestListGzMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.supplierfleet.SupplierFleetMapper;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import javax.annotation.Resource;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;

/**
 * ERP广州制单 Service 实现类
 * @author 天使管理员
 */
@Service
@Validated
public class DpGzServiceImpl implements DpGzService {

    @Resource
    private DpGzMapper dpGzMapper;
    @Resource
    private DpItemGzMapper dpItemGzMapper;
    @Resource
    private DpEastListGzMapper dpEastListGzMapper;
    @Resource
    private DpWestListGzMapper dpWestListGzMapper;
    @Resource
    private DispatchVehicleMapper dispatchVehicleMapper;
    @Resource
    private DpServiceImpl dpServiceImpl;
    @Resource
    private DpMapper dpMapper;
    @Resource
    private SupplierFleetMapper supplierFleetMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createDpGz(DpGzSaveReqVO createReqVO) {
        // 插入
        DpGzDO dpGz = BeanUtils.toBean(createReqVO, DpGzDO.class);
        dpGzMapper.insert(dpGz);
        // 插入子表
        createDpItemGzList(dpGz.getId(), createReqVO.getDpItemGzs());
        createDpEastListGzList(dpGz.getId(), createReqVO.getDpEastListGzs());
        createDpWestListGzList(dpGz.getId(), createReqVO.getDpWestListGzs());
        createDispatchVehicle(createReqVO.getDispatchVehicleDOS());
        // 返回
        return dpGz.getId();
    }

//    @Override
//    public Boolean configCar(String dispatchNumber, List<DispatchorderitemGzSaveReqVO> createReqVO) {
////        List<Long> itemIds = dpItemGzMapper.selectListByNos(ids);
//        List<DispatchorderitemGzDO> dispatchorderitemGzDOS = new ArrayList<>();
//        List<Long> ids = createReqVO.stream().map(DispatchorderitemGzSaveReqVO::getId).collect(Collectors.toList());
//        dispatchorderitemGzMapper.deleteByItemIds(ids);
//        for (int i = 0; i < createReqVO.size(); i++) {
//            DispatchorderitemGzDO dispatchorderitemGzDO = new DispatchorderitemGzDO();
//            dispatchorderitemGzDO.setDispatchNumber(dispatchNumber);
//            dispatchorderitemGzDO.setItemId(createReqVO.get(i).getId());
//            dispatchorderitemGzDO.setNo(createReqVO.get(i).getNo());
//            dispatchorderitemGzDOS.add(dispatchorderitemGzDO);
//        }
//        return dispatchorderitemGzMapper.insertBatch(dispatchorderitemGzDOS);
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDpGz(DpGzSaveReqVO updateReqVO) {
        // 更新
        DpGzDO updateObj = BeanUtils.toBean(updateReqVO, DpGzDO.class);
        dpGzMapper.updateById(updateObj);
        // 更新子表
        updateDpItemGzList(updateReqVO.getId(), updateReqVO.getDpItemGzs());
        updateDpEastListGzList(updateReqVO.getId(), updateReqVO.getDpEastListGzs());
        updateDpWestListGzList(updateReqVO.getId(), updateReqVO.getDpWestListGzs());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDpGz(String id) {
        // 删除
        dpGzMapper.deleteById(id);
        // 删除子表
        deleteDpItemGzByNo(id);
        deleteDpEastListGzByNo(id);
        deleteDpWestListGzByNo(id);
    }

    @Override
    public DpGzDO getDpGz(String id) {
        return dpGzMapper.selectById(id);
    }

    @Override
    public PageResult<DpGzDO> getDpGzPage(DpGzPageReqVO pageReqVO) {
        return dpGzMapper.getDpGzPage(pageReqVO);
    }

    @Override
    public PageResult<DpGzDO> dpGzOuterList(DpGzPageReqVO pageReqVO) {
        return dpGzMapper.selectRemCountNoZeroPage(pageReqVO);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dpGzOutStroe(DispatchVehicleSaveReqVO createReqVO) {
        List<DpGzDO> dpGzDOList= createReqVO.getDpGzDOList();
        //出库到国外仓更新总制单表出库状态为1
        Integer isForeign = createReqVO.getDest() > 7 ? 1 : 0;
        List<DpDO> dpList = new ArrayList<>();
        //防止修改总制单其他字段数据，只修改相应字段
        for (DpGzDO dpDO : dpGzDOList) {
            DpDO dp = new DpDO();
            dp.setId(dpDO.getId());
            dp.setInventoryStatus(1);
            dp.setIsForeign(isForeign);
            dpList.add(dp);
        }
        dpMapper.updateBatch(dpList);
        //修改运表单数据
        for (DpGzDO dpGzDO : dpGzDOList) {
            //设置剩余件数 = 剩余总件数 - 出库件数
            Integer outCount = dpGzDO.getOutCount();
            int remCount = dpGzDO.getRemCount() - (outCount == null ? 0 : outCount);
            if (remCount < 0) {
                throw exception(DP_COUNT_OUTOF_MAX);
            }else {
                dpGzDO.setRemCount(remCount);
            }
            //设置剩余体积 = 剩余总体积 - 出库体积
            Double outVolume = dpGzDO.getOutVolume();
            double remVolume = dpGzDO.getRemVolume() - (outVolume == null ? 0 : outVolume);
            if (remVolume < 0) {
                throw exception(DP_VOLUME_OUTOF_MAX);
            }else {
                dpGzDO.setRemVolume(remVolume);
            }
            //设置剩余重量 = 剩余总重量 - 出库重量
            Double outWeight = dpGzDO.getOutWeight();
            double remWeight = dpGzDO.getRemWeight() - (outWeight == null ? 0 : outWeight);
            if (remWeight < 0) {
                throw exception(DP_WEIGHT_OUTOF_MAX);
            }else {
                dpGzDO.setRemWeight(remWeight);
            }
        }

        //批量修改制单数据
        dpGzMapper.updateById(dpGzDOList);

        //往对应仓库插入数据
//        Integer dest = createReqVO.getDest();
//        List<DpGzDO> dps = new ArrayList<>();
//        for (DpGzDO dpGzDO : dpGzDOList) {
//            dpGzDO.setInventoryStatus(1);
//            dpGzDO.setRemCount(dpGzDO.getOutCount());
//            dpGzDO.setRemVolume(dpGzDO.getOutVolume());
//            dpGzDO.setRemWeight(dpGzDO.getOutWeight());
//            dps.add(dpGzDO);
//        }
//        List<DpDO> dpDOS = BeanUtils.toBean(dps, DpDO.class);
//        dpServiceImpl.insertDpByDest(dest,dpDOS);

        //处理配车表数据
        List<DispatchVehicleDO> dispDOs = new ArrayList<DispatchVehicleDO>();
        for (DpGzDO dpGzDO : dpGzDOList) {
            DispatchVehicleDO vehicleDO = BeanUtils.toBean(createReqVO, DispatchVehicleDO.class);
            //处理车数据
            vehicleDO.setDpId(dpGzDO.getId());
            vehicleDO.setNo(dpGzDO.getNo());
            vehicleDO.setDispatchNumber(createReqVO.getDispatchNumber());
            vehicleDO.setInventoryStatus(1);
            // 使用 Gson 将 dpYwDO 转换为 JSON 字符串
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // 注册 LocalDate 适配器
                    .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())  // 跳过 LocalDateTime 字段
                    .create();
            String dpDataJson = gson.toJson(dpGzDO);  // LocalDateTime 字段会被跳过
            // 设置 JSON 字符串到 createReqVO 的 dpData 字段
            vehicleDO.setDpData(dpDataJson);
            dispDOs.add(vehicleDO);
        }
        // 批量插入配车数据
        dispatchVehicleMapper.insertBatch(dispDOs);

        //插入数据到供应商车队
        List<DispatchVehicleDO> supplierList = createReqVO.getSupplierInfo();
        String dispatchNumber = createReqVO.getDispatchNumber();
        String department = createReqVO.getDepartment();
        //处理时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(new Date());
        createReqVO.setDate(formattedDate);
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        String recordDate = sdf2.format(new Date());
        createReqVO.setRecordDate(recordDate);
        createReqVO.setDpGzDOList(null);
        createReqVO.setSupplierInfo(null);
        List<SupplierFleetDO> fleetDOS = new ArrayList<>();
        for (DispatchVehicleDO supplierInfo : supplierList) {
            String fleet = supplierInfo.getFleet();
            if (fleet == null || fleet.trim().equals("")) {
                continue;
            }
            SupplierFleetDO supplierFleetDO = new SupplierFleetDO();
            supplierFleetDO.setType(1);
            supplierFleetDO.setCategory(supplierInfo.getCategory());
            supplierFleetDO.setName(supplierInfo.getSupplier());
            supplierFleetDO.setFleet(fleet);
            supplierFleetDO.setTotalAmount(supplierInfo.getExpense());
            //出库设置币种
            supplierFleetDO.setCurrencyType(supplierInfo.getCurrencyType());
            supplierFleetDO.setRemark(dispatchNumber);
            supplierFleetDO.setDepartment(department);

            // 处理info字段
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) // 注册 LocalDate 适配器
                    .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())  // 跳过 LocalDateTime 字段
                    .create();
            createReqVO.setCategory(supplierInfo.getCategory());
            createReqVO.setSupplier(supplierInfo.getSupplier());
            createReqVO.setFleet(fleet);
            createReqVO.setFare(supplierInfo.getFare());
            createReqVO.setExpense(supplierInfo.getExpense());
            createReqVO.setCurrencyType(supplierInfo.getCurrencyType());
            createReqVO.setRemark(dispatchNumber);
            createReqVO.setDepartment(department);
            String info = gson.toJson(createReqVO);
            supplierFleetDO.setInfo(info);
            fleetDOS.add(supplierFleetDO);
        }
        supplierFleetMapper.insertBatch(fleetDOS);
    }


    @Override
    public List<DispatchVehicleDO> dpGzEnterList(String dispatchNumber, Integer line, Integer inventoryStatus, Integer dest,String dpId) {
        return dispatchVehicleMapper.selectByDispatch(dispatchNumber, line, inventoryStatus, dest,dpId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void enterStroeDpGz(List<DispatchVehicleSaveReqVO> pageReqVO) {
        List<DispatchVehicleDO> list = BeanUtils.toBean(pageReqVO, DispatchVehicleDO.class);
        for (DispatchVehicleDO dispatchVehicleDO : list) {
            String dpData= dispatchVehicleDO.getDpData();
            JSONObject jsonObject = JSONObject.parseObject(dpData);
            DpGzDO dpGzDO = JSONObject.toJavaObject(jsonObject, DpGzDO.class);

            dpGzDO.setRemCount((Integer) jsonObject.get("outCount"));
            BigDecimal outVolume = jsonObject.getBigDecimal("outVolume");
            dpGzDO.setRemVolume(outVolume.doubleValue());
            BigDecimal outWeight = jsonObject.getBigDecimal("outWeight");
            dpGzDO.setRemWeight(outWeight.doubleValue());
            DpGzDO dpGzDO1 = dpGzMapper.selectById(dpGzDO.getId());
            dpGzDO.setInventoryStatus(2);
            if (dpGzDO1 != null) {
                dpGzDO.setRemCount(dpGzDO.getRemCount() + dpGzDO1.getRemCount());
                dpGzDO.setRemVolume(dpGzDO.getRemVolume() + dpGzDO1.getRemVolume());
                dpGzDO.setRemWeight(dpGzDO.getRemWeight() + dpGzDO1.getRemWeight());
                dpGzMapper.updateById(dpGzDO);
            } else {
                dpGzMapper.insert(dpGzDO);
            }

            dpMapper.enterDpStart(dpGzDO.getId());

            dispatchVehicleMapper.updateById(dispatchVehicleDO.setInventoryStatus(2));
        }
    }

    // ==================== 子表（ERP广州制单货号详情） ====================

    @Override
    public List<DpItemGzDO> getDpItemGzListByNo(String no) {
        return dpItemGzMapper.selectListByNo(no);
    }

    private void createDpItemGzList(String no, List<DpItemGzDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        dpItemGzMapper.insertBatch(list);
    }

    private void updateDpItemGzList(String no, List<DpItemGzDO> list) {
        deleteDpItemGzByNo(no);
        createDpItemGzList(no, list);
    }

    private void deleteDpItemGzByNo(String no) {
        dpItemGzMapper.deleteByNo(no);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void examineDpGz(DpGzDO dpGzDO) {
        //删除总表里面的对应单据
        dpServiceImpl.deleteDp(dpGzDO.getId());
        if (dpGzDO.getStatus() == 1){
            convertdpGzToDp(dpGzDO);
            dpGzMapper.updateById(dpGzDO);
        } else {
            //修改当前仓库的单据状态
            dpGzMapper.updateById(dpGzDO);
            DpGzDO gzDO = dpGzMapper.selectById(dpGzDO.getId());
            dpMapper.insert(BeanUtils.toBean(gzDO, DpDO.class));
        }

    }

    // ==================== 子表（广州东线清单） ====================

    @Override
    public List<DpEastListGzDO> getDpEastListGzListByNo(String no) {
        return dpEastListGzMapper.selectListByNo(no);
    }

    private void createDpEastListGzList(String no, List<DpEastListGzDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        dpEastListGzMapper.insertBatch(list);
    }

    private void updateDpEastListGzList(String no, List<DpEastListGzDO> list) {
        deleteDpEastListGzByNo(no);
//		list.forEach(o -> o.setId(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createDpEastListGzList(no, list);
    }

    private void deleteDpEastListGzByNo(String no) {
        dpEastListGzMapper.deleteByNo(no);
    }

    // ==================== 子表（广州西线清单） ====================

    @Override
    public List<DpWestListGzDO> getDpWestListGzListByNo(String no) {
        return dpWestListGzMapper.selectListByNo(no);
    }


    private void createDpWestListGzList(String no, List<DpWestListGzDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        dpWestListGzMapper.insertBatch(list);
    }

    private void updateDpWestListGzList(String no, List<DpWestListGzDO> list) {
        deleteDpWestListGzByNo(no);
//		list.forEach(o -> o.setId(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createDpWestListGzList(no, list);
    }

    private void deleteDpWestListGzByNo(String no) {
        dpWestListGzMapper.deleteByNo(no);
    }


    private void createDispatchVehicle(List<DispatchVehicleDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        dispatchVehicleMapper.insertBatch(list);
    }

    // 将 GpGzSaveReqVO 转换为 DpSaveReqVO
    public void convertdpGzToDp(DpGzDO dpGzDO) {
        DpGzDO dpDo = dpGzMapper.selectById(dpGzDO.getId());
        //防止编辑时选了审核后插入总制单状态为1
        dpDo.setStatus(0);
        //设置剩余总件数
        dpDo.setRemCount(dpDo.getInCount());
        //设置剩余总体积
        dpDo.setRemVolume(dpDo.getInVolume());
        //设置剩余总重量
        dpDo.setRemWeight(dpDo.getWeight());
        //设置总欠款
        dpDo.setDebtTotal(dpDo.getTotalAmount());
        List<DpItemGzDO> dpItemGzDOList = dpItemGzMapper.selectListByNo(dpGzDO.getId());
        // 复制 DpGzSaveReqVO 中的属性到 DpSaveReqVO
        DpSaveReqVO createReqVO = BeanUtils.toBean(dpDo, DpSaveReqVO.class);
        createReqVO.setNotPoint(createReqVO.getCustomerRebate());
        if (createReqVO.getWriteOff() == 1){
            createReqVO.setNotWriteOff(createReqVO.getWriteExpenses());
        }
        List<DpItemDO> dpItems = BeanUtils.toBean(dpItemGzDOList, DpItemDO.class);
        //避免dp_item表的主键冲突
        dpItems.forEach(item -> item.setId(null));
        // 设置转换后的列表到 DpSaveReqVO
        createReqVO.setDpItems(dpItems);
        dpServiceImpl.createDp(createReqVO);
    }

}